#ifndef __RING_H__
#define __RING_H__

#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "cmsis_os.h"
#include "log.h"

// ##
#define SOFTWARE_VERSION        "v1.0.1"
#define SOFTWARE_AUTHOR         "liubingyan"

/*
 * ARM Compiler 4/5
 */
#if   defined ( __CC_ARM )

  #define __ASM            __asm
  #define __INLINE         __inline
  #define __STATIC_INLINE  static __inline

  #include "cmsis_armcc.h"

/*
 * GNU Compiler
 */
#elif defined ( __GNUC__ )

  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
  #define __STATIC_INLINE  static inline

  #include "cmsis_gcc.h"


/*
 * IAR Compiler
 */
#elif defined ( __ICCARM__ )

  #ifndef   __ASM
    #define __ASM                     __asm
  #endif
  #ifndef   __INLINE
    #define __INLINE                  inline
  #endif
  #ifndef   __STATIC_INLINE
    #define __STATIC_INLINE           static inline
  #endif

  #include <cmsis_iar.h>
#endif

typedef struct
{
	uint16_t head; 		// for read
	uint16_t tail; 		// for write
	osMutexId head_mutex;
	osMutexId tail_mutex;

	uint8_t *buf;
	uint16_t size;

	uint8_t saveFlag;

}ringType;

// ##
typedef ringType ringHandle;

// ##
uint16_t ring_unwrite_bytes(ringHandle *ring);

// ##
uint16_t ring_unread_bytes(ringHandle *ring);

/*
	output ring info
*/
void ring_print_info(ringHandle *ring);

/*
	create and initialize a new ring
*/
ringHandle *ring_create(ringType *newRing, uint8_t *newBuffer, uint16_t buf_len);

/*
	add one byte into ringbuffer
	return : real bytes added into ringbuffer
*/
uint16_t ring_add_single_byte(ringHandle *ring, const uint8_t newByte);

/*
	add bytes into ringbuffer
	return : real bytes added into ringbuffer
*/
uint16_t ring_add_bytes(ringHandle *ring, const uint8_t *buf, uint16_t size);

/*
	fetch bytes from ringbuffer
	return : real bytes fetched from ringbuffer
*/
uint16_t ring_fetch_bytes(ringHandle *ring, uint8_t *buf, uint16_t size);

#endif
